package com.kerpow.KSheet;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.DialogInterface.OnClickListener;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.LinearLayout;

import com.kerpow.KSheet.SheetListItem.OnSheetItemClickHandler;
import com.kerpow.KSheet.character.CharacterAdapter;
import com.kerpow.KSheet.character.Finder;
import com.kerpow.KSheet.character.CharacterAdapter.LoadState;
import com.kerpow.KSheet.character.Finder.OnFileFoundHandler;

public class KSheet extends Activity {
		 
	private static final int MENU_FIND = Menu.FIRST;
	
	private static final int DLG_CONFIRMCLEAR = 0;
	
	//private CharacterDBAdapter _db;
	
	ArrayList<File>  _files;
	
	LinearLayout _listLoaded; 
	LinearLayout _listSD; 
	
	FindSheetsTask _findTask;
	
	File _fileToClear;
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.ksheet);
        
        _listLoaded = (LinearLayout) findViewById(R.id.sheetlist_loaded);
        _listSD = (LinearLayout) findViewById(R.id.sheetlist_sd);

        GlobalSettings.Load(this);
    }
	@Override
	protected Dialog onCreateDialog(int id) {
		if(id == DLG_CONFIRMCLEAR){
			AlertDialog.Builder builder = new AlertDialog.Builder(this);
			builder.setMessage("This will unload the character data from KSheet but will not delete the .dnd4e file from your SD card. Do you wish to continue?")
			       .setCancelable(false)
			       .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
			           public void onClick(DialogInterface dialog, int id) {
				   			CharacterAdapter db = new CharacterAdapter(KSheet.this).open();	
							db.deleteCharacter(db.getCharacterID(_fileToClear.getAbsolutePath()));
					        db.close();
					        updateLists();
			           }
			       })
			       .setNegativeButton("No", new DialogInterface.OnClickListener() {
			           public void onClick(DialogInterface dialog, int id) {
			                dialog.cancel();
			           }
			       });
			AlertDialog alert = builder.create();
			return alert;
		}
		return super.onCreateDialog(id);
	}
	@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        menu.add(0, MENU_FIND, 0, R.string.menu_refreshfiles);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
        switch(item.getItemId()) {
        case MENU_FIND:
        	updateLists();
        	return true;
        }
		return super.onOptionsItemSelected(item);
	}
	@Override
	protected void onPause() {
		super.onPause();
		_findTask.cancel(true);
	}

	@Override
	protected void onResume() {
		super.onResume();
		
		updateLists();
	}
	
	private void updateLists(){
		_files = new ArrayList<File>();
		_listLoaded.removeAllViews();
		_listSD.removeAllViews();
		
		//get sheets in DB
		CharacterAdapter _db = new CharacterAdapter(KSheet.this).open();
		ArrayList<File> files = _db.fetchDBPaths();
        _db.close();
		
		for(File f : files){
			addFileToList(f, true);
		}
		
    	_findTask = new FindSheetsTask();
    	_findTask.execute();
        showFirstTimeDialog();
	}

	private void showFirstTimeDialog(){
		String currentVersion = getString(R.string.app_version);
		SharedPreferences prefs = getSharedPreferences(getString(R.string.app_name), MODE_PRIVATE);
		
		String prefVersion = prefs.getString("version", "unset");
		
		if(!currentVersion.equals(prefVersion)){	
			prefs.edit().putString("version", currentVersion).commit();
			
		    new AlertDialog.Builder(this)
		      .setMessage(getString(R.string.new_version_dialog))
		      .setPositiveButton(R.string.okbutton, null)
		      .setNegativeButton(R.string.openwebsitebutton, new OnClickListener() {
				
				@Override
				public void onClick(DialogInterface dialog, int which) {
					String url = getString(R.string.websiteurl);
					Intent i = new Intent(Intent.ACTION_VIEW);
					i.setData(Uri.parse(url));
					startActivity(i);
				}
			})
			.show();
		}
	}
	
	private void openFile(File file,LoadState state){

		if(state == LoadState.Ready || state == LoadState.CannotReload){
			//view it
			Intent i = new Intent(this,CharacterSheet.class);
			i.putExtra("path", file.getAbsolutePath());
			startActivity(i);
		}else{
			//load it
			Intent i = new Intent(this,LoadSheet.class);
			i.putExtra("path", file.getAbsolutePath());
			startActivity(i);
		}

	}
	public static String md5(String path) {  
	    try {  
	    	//get the bytes
	    	File file = new File(path);
	    	
	    	InputStream is = new FileInputStream(file);
	    	
	        // Get the size of the file
	        long length = file.length();

	        // You cannot create an array using a long type.
	        // It needs to be an int type.
	        // Before converting to an int type, check
	        // to ensure that file is not larger than Integer.MAX_VALUE.
	        if (length > Integer.MAX_VALUE) {
	            // File is too large
	        }

	        // Create the byte array to hold the data
	        byte[] bytes = new byte[(int)length];

	        // Read in the bytes
	        int offset = 0;
	        int numRead = 0;
	        while (offset < bytes.length
	               && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
	            offset += numRead;
	        }

	        // Close the input stream and return bytes
	        is.close();
	    	
	    	
	        // Create MD5 Hash  
	        MessageDigest digest = java.security.MessageDigest.getInstance("MD5");  
	        digest.update(bytes);  
	        byte messageDigest[] = digest.digest();  
	          
	        // Create Hex String  
	        StringBuffer hexString = new StringBuffer();  
	        for (int i=0; i<messageDigest.length; i++)  
	            hexString.append(Integer.toHexString(0xFF & messageDigest[i]));
	        
	        return hexString.toString();  
	          
	    } catch (NoSuchAlgorithmException e) {  
	        e.printStackTrace();  
	    } catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}  
	    return "";  
	}  
	
	private void addFileToList(File f, boolean stored){
		for(File file : _files){
			if(file.equals(f))return; //no dupe files
		}
		
		_files.add(f);
		CharacterAdapter.LoadState state = LoadState.Unkown;

		CharacterAdapter db = new CharacterAdapter(KSheet.this).open();	
		state = db.getLoadState(f.getAbsolutePath());
        db.close();

		SheetListItem sli = new SheetListItem(f, state,  this);
		
		sli.setOnSheetItemClickHandler(_sheetClickHandler);
		if(stored)
			_listLoaded.addView(sli);
		else
			_listSD.addView(sli);
	}
	
	private OnSheetItemClickHandler _sheetClickHandler = new OnSheetItemClickHandler() {


		@Override
		public void OnRefreshSheet(File f) {	
			//force load it
			Intent i = new Intent(KSheet.this,LoadSheet.class);
			i.putExtra("path", f.getAbsolutePath());
			startActivity(i);
			
			new FindSheetsTask().execute();
		}

		@Override
		public void OnOpenSheet(File f, LoadState state) {
			openFile(f,state);
		}

		@Override
		public void OnClearData(File f) {
			_fileToClear = f;
			showDialog(DLG_CONFIRMCLEAR);
		}
	};
	
	private class FindSheetsTask extends AsyncTask<Void, File, Void>{
		
		@Override
		protected Void doInBackground(Void... params) {

			
	        Finder finder = new Finder();
	        
	        finder.setOnFileFound(new OnFileFoundHandler() {
				
				@Override
				public void OnFileFound(File f) {
					FindSheetsTask.this.publishProgress(f);
				}
			});
	        
	        finder.getSheets();
	        
	        
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			Log.i("kerpow","Finished search");
			View prog = findViewById(R.id.sdsearchprogress);
			prog.setVisibility(View.GONE);
		
			super.onPostExecute(result);
		}

		@Override
		protected void onProgressUpdate(File... values) {
			//values[0] is a File
			
			File f = (File)values[0];
			
			addFileToList(f, false);
		}

		@Override
		protected void onPreExecute() {
			View prog = findViewById(R.id.sdsearchprogress);
			prog.setVisibility(View.VISIBLE);
			super.onPreExecute();
		}

	}

}